home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / game / wins1726.zip / NEWTON.ASM < prev    next >
Assembly Source File  |  1990-11-01  |  6KB  |  349 lines

  1. ; NEWTON.ASM : Procedure NewtonFractal() from FRACTINT.
  2. ; Lee Daniel Crocker, 4/23/89.
  3. ;
  4. ; Tabs: 8
  5. ;
  6. ; Modifications:
  7. ;   BT = Bert Tyler
  8. ;   TW = Timothy Wegner
  9. ;   RD = Robert Day
  10. ;   MP = Mark Peterson
  11. ;
  12. ; Note: newton.asm was totally rewritten by Lee Crocker for FRACTINT 10.0
  13. ;    for integration with the newly structured fractal engine in calcmand.c
  14. ;    and fractals.c. The current routine consists of the inner orbit
  15. ;    calculation, with the supporting code removed. Early versions of
  16. ;    newton.asm contained a complete newton fractal function.
  17. ;
  18. ; Assembled by Microsoft Macro Assembler 5.1, for use with Microsoft C 5.1.
  19. ;
  20.  
  21. ; Required for compatibility if Turbo ASM (BT 5/20/89)
  22.  
  23. IFDEF ??version
  24. MASM51
  25. QUIRKS
  26. EMUL
  27. ENDIF
  28.  
  29. .model    medium, c
  30.  
  31. public    NewtonFractal2
  32. public    invertz2
  33.  
  34. .data
  35.     extrn    color:word, maxcolor:word, degree:word, basin:word
  36.     extrn    row:word, col:word
  37.  
  38.     extrn    dx0:dword, dy0:dword
  39.     extrn    dx1:dword, dy1:dword
  40.  
  41.     extrn    old:qword, new:qword, d1overd:qword, roverd:qword
  42.     extrn    threshold:qword, floatmin:qword, floatmax:qword
  43.     extrn    f_radius:qword, f_xcenter:qword, f_ycenter:qword
  44.     extrn    roots:word, tempsqrx:qword
  45.  
  46. statw    dw    ?
  47.  
  48. .code
  49.  
  50. public    NewtonFractal2
  51. NewtonFractal2 proc
  52.  
  53. ;
  54. ; cpower(&old, degree-1, &tmp)
  55. ;
  56.     mov    ax, degree
  57.     dec    ax
  58.  
  59.     fld    old + 8
  60.     fld    old
  61. ;
  62. ; cpower() is expanded inline here.
  63. ;
  64.     shr    ax, 1
  65.     jnc    load1            ; if (exp & 1)
  66.  
  67.     fld    st(1)
  68.     fld    st(1)
  69.     jmp    short looptop        ; tmp = old
  70. load1:
  71.     fldz
  72.     fld1                ; else tmp = [1,0]
  73. looptop:
  74.     cmp    ax, 0
  75.     je    loopexit        ; while (exp)
  76.  
  77.     fld    st(2)            ; RD 5/7/89: Calculate xt^2 - yt^2
  78.     fadd    st, st(4)        ; by using (xt+yt)*(xt-yt), which
  79.     fld    st(3)            ; trades one multiplication for an
  80.     fsub    st, st(5)        ; addition.  This trick saves a
  81.     fmul                ; whopping 1.2% of time.
  82.  
  83.     fld    st(4)
  84.     fmul    st, st(4)
  85.     fadd    st, st            ; yt = 2 * xt * yt
  86.  
  87.     fstp    st(5)            ; tmp.y = yt
  88.     fstp    st(3)            ; tmp.x = xt
  89.  
  90.     shr    ax, 1
  91.     jnc    looptop         ; if (exp & 1)
  92.  
  93.     fld    st(2)
  94.     fmul    st, st(1)
  95.     fld    st(4)
  96.     fmul    st, st(3)
  97.     fsub                ; tmp.x = xt * tmp.x - yt * tmp.y
  98.  
  99.     fld    st(3)
  100.     fmul    st, st(3)
  101.     fld    st(5)
  102.     fmul    st, st(3)
  103.     fadd                ; tmp.y = xt * tmp.y + yt * tmp.x
  104.     fstp    st(3)
  105.     fstp    st(1)
  106.  
  107.     jmp    short looptop
  108. loopexit:
  109.     fstp    st(2)
  110.     fstp    st(2)
  111. ;
  112. ; End of complex_power() routine.  Result is in ST, ST(1)
  113. ;
  114. ;
  115. ; complex_mult(tmp, old, &new);
  116. ;
  117.     fld    old + 8
  118.     fld    old
  119.  
  120.     fld    st(3)        ; tmp.y
  121.     fmul    st, st(1)   ; old.x
  122.     fld    st(3)        ; tmp.x
  123.     fmul    st, st(3)   ; old.y
  124.     fadd
  125.     fld    st(3)        ; tmp.x
  126.     fmul    st, st(2)   ; old.x
  127.     fld    st(5)        ; tmp.y
  128.     fmul    st, st(4)   ; old.y
  129.     fsub
  130. ;
  131. ; if (DIST1(new) < THRESHOLD) {
  132. ;
  133.     fld1
  134.     fsubr    st, st(1)
  135.     fmul    st, st
  136.     fld    st(2)        ; new.y
  137.     fmul    st, st
  138.     fadd
  139.     fcomp    threshold
  140.     fstsw    statw
  141.     mov    ax, statw
  142.     sahf
  143.     jnc    notless
  144. ;
  145. ; if (fractype == NEWTBASIN) {
  146. ;
  147.     mov    ax, basin
  148.     cmp    ax, 0
  149.     je    notbasin
  150.  
  151.     mov    bx, roots
  152.     mov    dx, -1            ; tempcolor = -1
  153.     sub    cx, cx
  154. dloop:
  155.     fld    qword ptr [bx]    ; roots[i].x
  156.     fsub    st, st(3)    ; old.x
  157.     fmul    st, st
  158.     fld    qword ptr [bx+8]; roots[i].y
  159.     fsub    st, st(5)    ; old.y
  160.     fmul    st, st
  161.     fadd
  162.     fcomp    threshold
  163.     fstsw    statw
  164.     mov    ax, statw
  165.     sahf                ; if (distance(roots[i],old) < threshold)...
  166.     jnc    nl2
  167.  
  168. ; TW commented out next few lines and add dx,ax to eliminate newtbasin
  169. ; color shades per Phil Wilson's request 12/03/89
  170.  
  171. ; TW put it back in in response to another use as an option! 7/7/90
  172.     mov    dx, cx
  173.     cmp    basin,2            ; basin==2 is flag for stripes
  174.     jne    nostripes
  175.     mov    ax, color
  176.     and    ax, 1
  177.     shl    ax, 1
  178.     shl    ax, 1
  179.     shl    ax, 1
  180.  
  181.     and    dx, 7
  182.     add    dx, ax
  183. nostripes:
  184.     inc    dx            ; tempcolor = 1+(i&7)+((color&1)<<3)
  185.     jmp    short nfb        ; break
  186. nl2:
  187.     add    bx, 16
  188.     inc    cx
  189.     cmp    cx, degree
  190.     jl    dloop
  191. nfb:
  192.     mov    ax, dx
  193.     cmp    dx, -1
  194.     jne    notm1
  195.     mov    ax, maxcolor        ; if (tmpcolor == -1)...
  196. notm1:
  197.     mov    color, ax
  198. notbasin:
  199.     mov    ax, 1
  200.     jmp    nlexit
  201. notless:
  202.     fld    d1overd
  203.     fmul    st(2), st        ; new.y *= d1overd
  204.     fmul
  205.     fld    roverd
  206.     fadd                ; new.x = d1overd * new.x + roverd
  207.  
  208.     fld    st(5)        ; tmp.y
  209.     fmul    st, st
  210.     fld    st(5)        ; tmp.x
  211.     fmul    st, st
  212.     fadd
  213.     fcom    floatmin
  214.     fstsw    statw
  215.     mov    ax, statw
  216.     sahf                ; if (mod(tmp) < FLT_MIN) {
  217.     jnc    cont
  218.     mov    ax, 1
  219.     fstp    st
  220.     jmp    nlexit
  221. cont:
  222.     fld1
  223.     fdivr
  224.     fst    st(4)        ; old.y
  225.     fstp    st(3)        ; old.x
  226.  
  227.     fld    st(4)        ; tmp.x
  228.     fmul    st, st(1)   ; new.x
  229.     fld    st(6)        ; tmp.y
  230.     fmul    st, st(3)   ; new.y
  231.     fadd
  232.     fmulp    st(3), st   ; old.x
  233.  
  234.     fld    st(4)        ; tmp.x
  235.     fmul    st, st(2)   ; new.y
  236.     fld    st(6)        ; tmp.y
  237.     fmul    st, st(2)   ; new.x
  238.     fsub
  239.     fmulp    st(4), st   ; old.y    ; old = new / tmp
  240.  
  241. ; MP Orbit Bug Fix 11/1/90
  242. ;    fstp    new
  243. ;    fstp    new + 8
  244. ;    fstp    old
  245. ;    fstp    old + 8
  246.     fstp    st
  247.     fstp    st
  248.     fst    new
  249.     fstp    old
  250.     fst    new + 8
  251.     fstp    old + 8
  252.  
  253.     mov    ax, 0
  254.     jmp    nlx2
  255.  
  256. nlexit:
  257.  
  258. ;MP Orbit Bug Fix 11/1/90
  259. ;    fstp    new
  260. ;    fstp    new + 8
  261.     fstp    st
  262.     fstp    st
  263.     fstp    new
  264.     fstp    new + 8
  265.  
  266. nlx2:
  267.     fstp    st
  268.     fstp    st
  269.  
  270.     ret
  271. NewtonFractal2 endp
  272. ;
  273. ;
  274. ;
  275. public    invertz2
  276. invertz2 proc    uses si, zval:word    ; TW 11/03/89 changed zval to near
  277.  
  278.     fld    f_xcenter
  279.     fld    f_ycenter
  280.  
  281.     mov    bx, col
  282.     shl    bx, 1
  283.     shl    bx, 1
  284.     shl    bx, 1
  285.  
  286.     mov    cx, row
  287.     shl    cx, 1
  288.     shl    cx, 1
  289.     shl    cx, 1
  290.  
  291.     mov    ax, ds
  292.     lds    si, dx0
  293.     add    si, bx
  294.     fld    qword ptr [si]
  295.     mov    ds, ax
  296.     lds    si, dx1
  297.     add    si, cx
  298.     fld    qword ptr [si]
  299.     fadd
  300.     fsub    st, st(2)
  301.  
  302.     mov    ds, ax
  303.     lds    si, dy0
  304.     add    si, cx
  305.     fld    qword ptr [si]
  306.     mov    ds, ax
  307.     lds    si, dy1
  308.     add    si, bx
  309.     fld    qword ptr [si]
  310.     fadd
  311.     fsub    st, st(2)
  312.  
  313.     mov    ds, ax
  314.     fld    st(1)
  315.     fmul    st, st
  316.     fld    st(1)
  317.     fmul    st, st
  318.     fadd
  319.  
  320.     fcom    floatmin
  321.     fstsw    statw
  322.     mov    ax, statw
  323.     sahf
  324.     jnc    inl1
  325.  
  326.     fstp    st
  327.     fld    floatmax
  328.     jmp    icom
  329. inl1:
  330.     fld    f_radius
  331.     fdivr
  332. icom:
  333.     fst    tempsqrx
  334.  
  335.     fmul    st(2), st
  336.     fmul
  337.     faddp    st(2), st
  338.     faddp    st(2), st
  339.  
  340. ;    lds    si, zval    ; TW 11/03/89 zval is now a near pointer
  341.     mov    si, zval    ; TW
  342.     fstp    qword ptr [si+8]
  343.     fstp    qword ptr [si]
  344.  
  345.     ret
  346. invertz2 endp
  347.  
  348. END
  349.